package main

import (
	"fmt"
	"bytes"
)

var gTx = []*Transaction{}

const gReward = 50

//维护所有钱包地址的utxo集合，启动时加载
var gAllUtxoInfos = make(map[string]*[]UTXOInfo) //address -> utxoinfo集合

//var gLockingUtxoInfos = make(map[string][]UTXOInfo) //address -> utxoinfo集合
//var gNewSpenderUtxoInfos = make(map[string][]UTXOInfo)  //address -> utxoinfo集合
var gNewReceiverUtxoInfos = make(map[string][]UTXOInfo) //address -> utxoinfo集合

func init() {
	Welcome()
	fmt.Printf("系统初始化...\n")

	if !gfLoadUtxoInfos() {
		fmt.Printf("加载本地钱包的utxo失败!\n")

		if !IsFileExist(blockChainName) {
			fmt.Printf("区块链不存在，请先创建!\n")
		} else {
			fmt.Printf("账本异常!\n")
		}

		return
	}

	fmt.Printf("加载本地钱包的utxo成功!\n")
}

func gfLoadUtxoInfos() bool {

	bc := NewBlockChain()

	if bc == nil {
		return false
	}

	defer bc.Db.Close()

	ws := NewWallets()
	for _, address := range ws.GetAddresses() {
		//gAllUtxoInfos[address] = bc.FindMyUtxos(AddressToHash(address))

		//数组指针需要确认一下是否有问题//TODO
		utxos := bc.FindMyUtxos(AddressToHash(address))
		gAllUtxoInfos[address] = &utxos
	}

	return true
}

func gfLockUsedUtxoInfos(address string, infos []UTXOInfo) {
	fmt.Printf("锁定已经消耗的utxo...\n")
	utxoinfos := gAllUtxoInfos[address]

	for i, utxoinfo := range *utxoinfos {
		//把utxoinfos中的intfos全部标识为lock: true
		for j, info := range infos {
			if bytes.Equal(utxoinfo.TXID, info.TXID) && utxoinfo.Index == info.Index {
				fmt.Printf("lock: %d\n", utxoinfo.Index)

				(*utxoinfos)[i].locking = true

				//去除这个
				infos = append(infos[:j], infos[j+1:]...)
				continue
			}
		}
	}
}

func gfUpdateSpenderUtxoinfos(from string, utxo UTXOInfo) {
	fmt.Printf("更新找零utxo...\n")
	utxoinfos := gAllUtxoInfos[from]

	//先加到最后，应该加载最前面比较好
	*utxoinfos = append(*utxoinfos, utxo)
	fmt.Printf("utxoinfos len : %d\n", len(*gAllUtxoInfos[from]))
}

func gfUpdateReceiverUtxoinfos() {
	fmt.Printf("更新收款人的utxo...\n")

	for receiver, newUtxoinfos := range gNewReceiverUtxoInfos {
		fmt.Printf("当前收款人地址: %s\n", receiver)
		utxoinfos := gAllUtxoInfos[receiver]
		if utxoinfos == nil {
			fmt.Printf("%s 不是钱包中的地址, 不统计!\n", receiver)
			continue
		}

		*utxoinfos = append(*utxoinfos, newUtxoinfos...)
	}
}

func gfUpdateMinnerUtxoinfos(miner string, coinbase *Transaction) {

	fmt.Printf("矿工的utxo...\n")

	utxoinfos := gAllUtxoInfos[miner]
	if utxoinfos == nil {
		fmt.Printf("%s 不是钱包中的地址, 不统计!\n", miner)
		return
	}
	utxoinfo := UTXOInfo{coinbase.TXID, -1, coinbase.TXOutputs[0], false}
	*utxoinfos = append(*utxoinfos, utxoinfo)
}
